function aa(...)
    local str = ...
    local idx, crc = pack.unpack(str:sub(-2, -1), "H")
    local tmp = str:sub(1, -3)
    if crc == crypto.crc16("MODBUS", tmp) then
        local idx, addr, fun, count, v1, v2 = pack.unpack(tmp, ">b3H2") -->b3H4 '>' 大字节序，3个按单字节解析，2个按无符号短整型(unsigned short，两字节)
        if fun == 0x03 then
            local t = {}
            t.addr = addr
            t.fun = fun
            t.v1 = v1
            t.v2 = v2
            t.res = str
            return json.encode(t)
        end
    end
    return str
end

----自定义协议----山东晨硕超声波流量计
-- 1、最后一行一定要有换行符
-- 2、字符串一定要用双引号
-- 3、发送时去掉函数名aa(...)
-- 4、local cfg = ... 可以获取两个系统参数cfg[1]=dtu , cfg[2]=udtu
function aa(...)
    -- 内部函数
    function _pro(d)
        v_hex = data:sub(6, 7) .. data:sub(4, 5)
        val = tonumber(v_hex:toHex(), 16)
        lcd.LCD_DATA[3] = "累计流量：" .. val
        usrdata.update(val)
    end

    local read_dat = "0103000E0002A5C8"
    power.openBoost()
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then
                _pro(data)
            end
            sys.wait(5000)
        else
            lcd.LCD_DATA[3] = "READ TIMEOUT"
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

function MBmag(...)
    function _pro(d)
        local _, ins = pack.unpack(data:sub(4, 7), ">f")
        local val = tonumber((data:sub(8, 11)):toHex(), 16)
        lcd.LCD_DATA[3] = "累计流量：" .. val
        usrdata.update({ val, ins })
    end

    local read_dat = "010310100004410C"
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then
                _pro(data)
                sys.publish("NET_SENT_RDY_1", data)
            end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

-- 青岛万水
function qdws(...)
    function _pro(d)
        if d:byte(3) == 16 then
            lcd.LCD_DATA[3] = "累计流量：" .. val
            usrdata.update()
        end
    end

    local read_dat = "0A03A02B0004177A"
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then _pro(data) end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

-- 青岛万水
function qdwsTest(...)
    function _pro(d)
        if d:byte(3) == 16 then
            local _, val = pack.unpack(data:sub(14, 15) .. data:sub(12, 13), ">f")
            if val then usrdata.update(val) end
        end
    end
    local read_dat = "0A03A02B0004177A"
    local read_dat = "0A 03 03 E8 00 08 C5 07"
    local read_dat = "0A 03 07 D0 00 08 45 FA" -- OK
    sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
    sys.wait(200)
    while true do
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then _pro(data) end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

-- 北京九迪 --波特率
--[[ 
    1A1 条线设置为，RS485，2400 偶校验，九迪协议
    Q=17.58L/S M=20188058 ......07BB
 ]]

function bjjdTest(...)
    while true do
        local r = "11"
        sys.publish("UART_SENT_RDY_3", 3, r:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then
                local arr = string.split(data, " ")
                local val = arr[3]:sub(3)
                lcd.LCD_DATA[3] = "累计流量：" .. val
                usrdata.update(val)
            end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

--[[ 浙江天信仪表 
    TO:01 03 00 02 00 0B A5 CD
    RE:01 03 16                ；地址、功能码、字节计数
       00 00 00 00             ；体积(瞬时)流量：0.0 m3/h
       3F F3 C0 CA 2A 5B 1D 5D ；正向总量：1.2345 m3
       3F F3 C1 C5 B8 52 65 5D ；反向总量：1.2348 m3
       00 02                   ；仪表状态字:0002 (状态：空管)
       7B 22                   ；CRC
 ]]
function zjtxybTest(...)
    while true do
        local r = "01030002000BA5CD"
        sys.publish("UART_SENT_RDY_3", 3, r:fromHex())
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res and d then
            local _, ins = pack.unpack(d:sub(4, 7), ">f")
            local _1, val = pack.unpack(d:sub(8, 15), ">d")
            local vals = string.format("%.2f", val)
            lcd.LCD_DATA[3] = "累计流量：" .. vals
            usrdata.update({ vals, ins })
        else
            sys.publish("NET_SENT_RDY_1", "READ ERROR")
        end
        sys.wait(5000)
    end
end

--[[上海博元测试,modbus地址 10
+--------+-------------------------------------------------+----------------+
|00000000| 0a 03 14 00 02 54 1a 00 00 00 00 07 a0 00 06 a2 |.....T..........|
|00000010| 16 02 3b 00 06 ae 6e 4b 78                      |..;...nKx       |
+--------+-------------------------------------------------+----------------+
+--------+-------------------------------------------------+----------------+
|00000000| 0a 03 14 00 02 55 3a 00 00 00 00 07 a4 00 06 a2 |.....U:.........|
|00000010| 2d 00 e8 00 06 ae 85 58 c2                      |-......X.       |
+--------+-------------------------------------------------+----------------+
+--------+-------------------------------------------------+----------------+
|00000000| 0a 03 14 00 02 58 ae 00 00 00 00 07 af 00 06 a2 |.....X..........|
|00000010| 42 02 89 00 06 ae 9a a3 41                      |B.......A       |
+--------+-------------------------------------------------+----------------+
+--------+-------------------------------------------------+----------------+
|00000000| 0a 03 14 00 00 00 00 00 00 00 00 00 34 00 06 a2 |............4...|
|00000010| d9 00 85 00 06 af 31 03 23                      |......1.#       |
+--------+-------------------------------------------------+----------------+
+--------+-------------------------------------------------+----------------+
|00000000| 0a 03 14 00 00 00 00 00 00 00 00 00 35 00 06 a3 |............5...|
|00000010| 3d 00 4f 00 06 af 95 fb b6                      |=.O......       |
+--------+-------------------------------------------------+----------------+

]]
function shanghaiBY(...)
    function _pro(d)
        local ins = tonumber((d:sub(4, 7)):toHex(), 16) / 1000
        local val = tonumber((d:sub(20, 23)):toHex(), 16)
        lcd.LCD_DATA[3] = "累计流量：" .. val
        usrdata.update({ val, ins })
    end

    local read_dat = "0A 03 00 00 00 0A C4 B6"
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then
                _pro(data)
                sys.publish("NET_SENT_RDY_1", data)
            end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end

--[[ 
    晨硕光电直读，自定义协议,9600,EVEN
 ]]
function csgdzd()
    function _pro(d)
        val = tonumber(d:sub(4, 7):toHex(), 16) 
        usrdata.update(val)
        lcd.LCD_DATA[3] = '累计流量:' .. (val or 'ERROR')
    end
    read_dat = "0103020200026473"
    power.openBoost()
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        local result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then
                _pro(data)
            end
            sys.wait(5000)
        else sys.publish("NET_SENT_RDY_1", "READ ERROR")
        end
    end
end


--[[ 
    晨硕超声波，自定义协议,9600,EVEN
    读取地址：00030000000185DB
 ]]
function CHENSHUO_CSB()
    function _pro(d)
        v_hex = d:sub(6, 7) .. d:sub(4, 5)
        meter_val = tonumber(v_hex:toHex(), 16) / 10
        usrdata.update(meter_val)
    end
    read_dat = "0103000E0002A5C8"
    power.openBoost()
    sys.wait(200)
    while true do
        sys.publish("UART_SENT_RDY_3", 3, read_dat:fromHex())
        result, data = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if result then
            if data then _pro(data) end
            sys.wait(5000)
        else
            lcd.LCD_DATA[3] ="READ TIMEOUT"
        end
    end
end

--[[ 
    上海匡建
    --0103000000104406
 ]]
 function SHKJ()
    function _pro(d)
        local _, ins = pack.unpack(d:sub(4, 7), ">f")
        local val = tonumber((d:sub(12, 15)):toHex(), 16)
        lcd.LCD_DATA[3] = "累计流量：" .. val
        usrdata.update({val, string.format("%.2f", ins)})
    end
    power.openBoost()
    sys.wait(200)
    local r = "0103000000104406"
    while true do
        sys.publish("UART_SENT_RDY_3", 3, r:fromHex())
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            if d then _pro(d) end
            sys.wait(5000)
        else
            lcd.LCD_DATA[3] = "READ TIMEOUT"
        end
    end
end

--[[ 
    济源小浪底
    --功能码：04，累计：0x0304 4字节 uint
 ]]
 function jyxld()
    function _pro(d)
        local val = tonumber((d:sub(4, 7)):toHex(), 16)
        lcd.LCD_DATA[3] = "累计流量：" .. val
        usrdata.update({val})
    end
    sys.wait(200)
    while true do
        local rc = "010403040002304E"
        sys.publish("UART_SENT_RDY_3", 3, rc:fromHex())
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            sys.publish("NET_SENT_RDY_1", d)
            if d then _pro(d) end
            sys.wait(5000)
        else
            lcd.LCD_DATA[3] = "READ TIMEOUT"
        end
    end
end
--[[ 
    西门子 19200，8，偶，1
    --功能码：03，累计：0x0304 4字节 uint
    01 03 0B BA 00 02 E7 CA -- 瞬时流量 float
    01 03 0B C6 00 04 A6 10 -- 累计1 double

 ]]
function xmz()
    function _pro(d)
        local _, val = pack.unpack(d:sub(4, 11), ">d")
        val = val and math.floor(val)
        lcd.LCD_DATA[3] = "累计：" .. val
        usrdata.update({val})
    end
    sys.wait(200)
    while true do
        local rc = "01 03 0B C6 00 04 A6 10"
        sys.publish("UART_SENT_RDY_3", 3, rc:fromHex())
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            sys.publish("NET_SENT_RDY_1", d)
            if d then _pro(d) end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "READ TIMEOUT")
        end
    end
end
--GF9900 Modbus 模块,19200,偶
--永城龙宇化工开控水务1#
function test()
    function _pro(d)
        local _, ins = pack.unpack(d:sub(4, 7), ">f")
        local _, val = pack.unpack(d:sub(8, 11), ">f")
        lcd.LCD_DATA[3] = "累计流量："..val
        usrdata.update({val, string.format("%.2f", ins)})
    end
    sys.wait(200)
    while true do
        tools.modbus_send(3,34,3,2,4)
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            sys.publish("NET_SENT_RDY_1", d)
            if d then _pro(d) end
            sys.wait(5000)
        else
           sys.publish("NET_SENT_RDY_1", "READ ERROR")
        end
    end
end
--深圳建恒
-- 01 03 00 04 00 06 84 09 
-- 01030c 5e92 43c3 4886 3eb2 c51a 001e b96a
function SZJH()
    function _pro(d)
        local _, ins = pack.unpack(d:sub(6, 7)..d:sub(4, 5), ">f")
        local _, val = pack.unpack(d:sub(14, 15)..d:sub(12, 13), ">I")
        lcd.LCD_DATA[3] = "累计流量："..val
        usrdata.update({val, string.format("%.2f", ins)})
    end
    sys.wait(200)
    while true do
        tools.modbus_send(3,addr,3,4,6)
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            sys.publish("NET_SENT_RDY_1", d)
            if d then _pro(d) end
            sys.wait(5000)
        else
           sys.publish("NET_SENT_RDY_1", "JH READ ERROR")
        end
    end
end
-- L-MAG511协议
-- 瞬时：tools.modbus_send(3,1,4,0,5)，short(4,5) 两个字节
-- 累计：tools.modbus_send(3,1,4,5,5)，long(4,5) 4个字节，大端
function test2()
    local tmp,val,ins
    function _pro(d)
        if isV then
            tmp, val = pack.unpack(d:sub(4, 7), ">I")
            isV = false
            lcd.LCD_DATA[3] = "累计："..val
        else
            tmp, ins = pack.unpack(d:sub(4, 5), ">H")
            isV = true
            lcd.LCD_DATA[3] = "瞬时："..ins
        end
        if val and ins then
            usrdata.update({val,ins})
        end
    end
    while true do
        if isV then
            tools.modbus_send(3,1,4,5,5)
        else
            tools.modbus_send(3,1,4,0,5)
        end
       
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            if d then _pro(d) end
            sys.wait(5000)
        else
           sys.publish("NET_SENT_RDY_1", "READ ERROR")
        end
    end
end
-- 安徽天维


function init()
    localaddr = udtu.addr and tonumber(udtu.addr) or 1
    function _pro(d)
        local _, val = pack.unpack(d:sub(4, 7), ">I")
        val = val and val/100
        lcd.LCD_DATA[3]= "累计:"..val
        usrdata.update(val)
    end
	while true do
        local rc = "370300000002C19D"
        sys.publish("UART_SENT_RDY_3", 3, rc:fromHex())
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3" , 5000)
        if res then
            if d then
                sys.publish("NET_SENT_RDY_1", string.toHex(d))
                _pro(d)
            end
            sys.wait(5000)
        else
            sys.publish("NET_SENT_RDY_1", "AHTW READ ERROR")
        end
	end
end
--[[+-------------------------------------------------+
|           0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+
|00000000| 0c 04 10 10 00 02 75 d3 0c 04 04 43 9e 19 9a d8 |
|00000010| d5 0c 04 10 18 00 02 f4 11 0c 04 04 00 14 0c d9 |
|00000020| a3 da                                           |
+--------+-------------------------------------------------+
LMAG 并联其他设备 ]]
 
function init()
	while true do
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3" , 5000)
        if res then
            if #d==34 then
                local _1,ins=pack.unpack(data:sub(11,14),">f")
                ins = string.format("%.2f",ins)
                local _2,val=pack.unpack(data:sub(29,32),">I")
                usrdata.update({val, ins})
                if lcd.LCD_DATA[3]:match("累计(.+)") then
                    lcd.LCD_DATA[3] ="顺时:"..(ins or "NULL")
                else
                    lcd.LCD_DATA[3] ="累计:"..(val or "NULL")
                end
            end
        else
            sys.publish("NET_SENT_RDY_1", "READ ERROR")
        end
	end
end
-- 牛王滩 开封渠道流量计
--[[
    流量 0x00 2有符号整型数 1.00E-03 m3/s
    水位 0x08 2 无符号整型数 1.00E-03 m
    正累计 0x10 3 无符号整型数 1.00E-02 m3 
]]
function name()
    local addr={{0,2,0.001},{8,2,0.001},{16,3,0.01}}
    while true do
        tools.modbus_send(3,1,3,16,3)
        local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
        if res then
            if d then
                local s = d:sub(4, -3)
                s=s:toHex()
                usrdata.update({"HEX",0.01,s})
                lcd.LCD_DATA[3] = "累计流量："..val
            end
            sys.wait(5000)
        end
    end
end
function name2()
    local addr = { { 0, 2, 0.001 }, { 8, 2, 0.001 }, { 16, 3, 0.001 } }
    while true do
        local data = {};
        for k, v in pairs(addr) do
            tools.modbus_send(3, 1, 3, v[1], v[2])
            local res, d = sys.waitUntil("UART_READ_DONE_NEXT_3", 5000)
            if res then
                local h = d:sub(4, -3):toHex()
                if v[1] == 16 then
                    data[1] = "HEX"
                    data[2] = v[3]
                    data[3] = h
                elseif v[1] == 0 then
                    data[4] = v[3]
                    data[5] = h
                elseif v[1] == 8 then
                    data[6] = v[3]
                    data[7] = h
                end
            end
        end
        if #data > 6 then
            usrdata.update(data)
        end
        sys.wait(2000)
    end
end
